package ru.ifmo.ctd.intsys.afanasyeva.boosting;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;

class Perceptron implements Classifier{
	private double[] weight;
	private final double learnSpeed;
	
	public Perceptron (int n, double learnSpeed) {
		weight = new double[n];
		this.learnSpeed = learnSpeed;
	}
	
	public void train(double[][] trainIn, double[] trainOut, int steps) {
		reset();
		for (int i = 0; i < steps; i++) {
			step(trainIn, trainOut);
		}
	}
	
	public boolean step(double[][] input, double[] output) {
		boolean changed = false;
		
		for (int j = 0; j < output.length; j++) {
			double out = getOutput(input[j]);			
			if (out != output[j]) {
				changed = true;
				for (int i = 0; i < input[j].length; i++) {
					weight[i] = 
						weight[i] + learnSpeed * (output[j] - out)*input[j][i];
				}
			}
		}
		
		return changed;
	}
	
	public double getOutput(double[] input) {
		double sum = 0;
		for (int i = 0; i < input.length; i++) {
			sum += weight[i] * input[i];
		}
		return Math.signum(sum) <= 0 ? -1 : 1;
	}
	
	public void print(Writer writer) throws IOException {
		for (double w : weight) {
			writer.append(w + " ");
		}
	}
	
	public void load(Reader reader) throws IOException {
		String string = (new BufferedReader(reader)).readLine();
		String[] array = string.split(" ");
		for (int i = 0; i < array.length; i++) {
			weight[i] = Double.parseDouble(array[i]);
		}
	}
		
	private void reset() {
		Arrays.fill(weight, Math.random());
	}	
}
